Master containerization from fundamentals to production: images, Dockerfiles, multi-stage builds, Docker Compose, orchestration, security best practices, and performance optimization.
Understanding the foundations: containers vs VMs, images, layers, and the Docker ecosystem.
Containers share the host OS kernel, making them lightweight and fast to start. VMs include full OS, requiring more resources but providing stronger isolation.
Docker images are built from read-only layers. Each Dockerfile instruction creates a new layer, enabling efficient storage and distribution.
Docker Engine manages container lifecycle: creation, execution, networking, and resource allocation through containerd and runc.
Docker provides multiple networking modes for container communication: bridge, host, overlay, and custom networks.
Containers are ephemeral by design. Use volumes and bind mounts for persistent data storage across container lifecycles.
Understanding states: created, running, paused, stopped, and the commands to manage transitions between these states.
# Image operations
docker build -t myapp:latest .
docker pull ubuntu:20.04
docker images
docker rmi image_id
# Container lifecycle
docker run -d --name web -p 80:8080 nginx
docker ps -a
docker exec -it web /bin/bash
docker logs web
docker stop web
docker rm web
# Network and volumes
docker network create mynet
docker volume create mydata
docker run -v mydata:/data ubuntu
Crafting efficient, secure, and maintainable container images with advanced Dockerfile techniques.
FROM: Base image selectionRUN: Execute commands during buildCOPY: Add files from build contextADD: COPY with URL/tar extractionWORKDIR: Set working directoryENV: Set environment variablesEXPOSE: Document port usageCMD: Default command to runENTRYPOINT: Immutable startup commandUSER: Set execution userHEALTHCHECK: Container health monitoring# Build stage
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
RUN npm run build
# Production stage
FROM node:16-alpine AS production
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
WORKDIR /app
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package.json ./
USER nextjs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
Orchestrating complex applications with multiple services, databases, and networking.
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile.prod
args:
NODE_ENV: production
ports:
- "80:3000"
environment:
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
- REDIS_URL=redis://redis:6379
volumes:
- ./uploads:/app/uploads
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
db:
image: postgres:14-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
secrets:
- db_password
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d myapp"]
interval: 10s
timeout: 5s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./ssl:/etc/ssl:ro
depends_on:
- web
restart: unless-stopped
volumes:
postgres_data:
driver: local
redis_data:
driver: local
secrets:
db_password:
file: ./secrets/db_password.txt
networks:
default:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
# Development workflow
docker-compose up -d
docker-compose logs -f web
docker-compose exec web npm test
docker-compose down
# Production deployment
docker-compose -f docker-compose.prod.yml up -d
docker-compose -f docker-compose.prod.yml pull
docker-compose -f docker-compose.prod.yml restart web
# Scaling services
docker-compose up -d --scale web=3
docker-compose ps
Scaling beyond single hosts with orchestration platforms, focusing on Kubernetes fundamentals.
Master-node architecture with control plane managing worker nodes running containerized workloads.
Essential Kubernetes objects for application deployment and management.
Docker's native orchestration solution for simpler cluster management.
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: myapp:v1.2.0
ports:
- containerPort: 3000
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: app-secrets
key: database-url
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 3000
type: LoadBalancer
Securing containers throughout the development lifecycle and in production environments.
# Vulnerability scanning with Trivy
trivy image myapp:latest
# Docker Bench Security audit
docker run --rm --net host --pid host --userns host --cap-add audit_control \
-e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
-v /etc:/etc:ro \
-v /usr/bin/containerd:/usr/bin/containerd:ro \
-v /usr/bin/runc:/usr/bin/runc:ro \
-v /usr/lib/systemd:/usr/lib/systemd:ro \
-v /var/lib:/var/lib:ro \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--label docker_bench_security \
docker/docker-bench-security
# Secure Dockerfile example
FROM node:16-alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
WORKDIR /app
COPY --chown=appuser:appgroup . .
USER appuser
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "server.js"]
Practice Docker concepts with simulated environments and tools.
Enterprise-grade patterns for scalable, maintainable containerized applications.
Assess your containerization expertise with comprehensive checklists and Q&A.
Docker Swarm is simpler and integrated with Docker, ideal for smaller deployments. Kubernetes offers more features, better ecosystem, and enterprise-grade orchestration but with higher complexity. Swarm uses docker-compose files, while K8s uses YAML manifests with more granular resource definitions.
Never embed secrets in images or environment variables. Use Docker secrets, Kubernetes secrets, or external secret managers like HashiCorp Vault. Mount secrets as files, rotate regularly, encrypt at rest and in transit, and audit access.
Use multi-stage builds, minimal base images (alpine, distroless), layer caching optimization, .dockerignore files, combine RUN commands, remove package caches, and use specific versions instead of 'latest' tags.
Use rolling updates, blue-green deployments, or canary releases. Implement health checks, graceful shutdowns, load balancer integration, and database migration strategies that don't break backwards compatibility.
Root containers can escape to host system, access sensitive files, and compromise other containers. Always use non-root users, drop unnecessary capabilities, use read-only filesystems, and implement Pod Security Standards in Kubernetes.